//
//  MultipeerConnectivityManager.m
//  MessangerSkeleton
//
//  Created by User-23 on 4/26/14.
//  Copyright (c) 2014 IOTrainingCamp. All rights reserved.
//

#import "MultipeerConnectivityManager.h"
#import "GamePlay.h"

@interface MultipeerConnectivityManager()

@property(nonatomic) GamePlay *gamePlay;

@end

@implementation MultipeerConnectivityManager
static BOOL isInited;



#pragma mark - init a Singleton object
+ (id)sharedInstance
{
    static MultipeerConnectivityManager *instance = nil;
    if ( !instance ) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            instance = [[super alloc] init];
        });
    }
    return instance;
}

+ (id)alloc
{
    return [MultipeerConnectivityManager sharedInstance];
}

- (id)init
{
    if ( !isInited ){
        self = [super init];
        if ( self ) {
            self.gamePlay = [GamePlay sharedInstance];
            
            _peerID = nil;
            _session = nil;
            _browser = nil;
            _advertiser = nil;

        }
    }
	return self;
}

#pragma mark -  Networking
#pragma mark -  starting session
- (void)startLookingForOponent
{
        NSLog(@"MC - looking for an opponent, I'm %@", [UIDevice currentDevice].name);
        [self setupPeerAndSessionWithDisplayName:[UIDevice currentDevice].name];
        //always should advertise if visible
        [self advertiseSelf:YES];
        
        [self setupMCBrowser];
        
        [self.browser setDelegate:self];
    
        [[CCDirector sharedDirector]  presentViewController:self.browser animated:YES completion:nil];

}

#pragma mark - setting peerID, browser and advertiser
-(void)setupPeerAndSessionWithDisplayName:(NSString *)displayName{
    _peerID = [[MCPeerID alloc] initWithDisplayName:displayName];
    
    _session = [[MCSession alloc] initWithPeer:_peerID];
    _session.delegate = self;
}

-(void)setupMCBrowser{
    _browser = [[MCBrowserViewController alloc] initWithServiceType:@"The-Messenger" session:_session];
    _browser.minimumNumberOfPeers = 2;
    _browser.maximumNumberOfPeers = 2;
}

-(void)advertiseSelf:(BOOL)shouldAdvertise{
    if (shouldAdvertise) {
        _advertiser = [[MCAdvertiserAssistant alloc] initWithServiceType:@"The-Messenger"
                                                           discoveryInfo:nil
                                                                 session:_session];
        [_advertiser start];
    }else{
        [_advertiser stop];
        _advertiser = nil;
    }
}

#pragma mark - found/not found a peer
-(void)browserViewControllerDidFinish:(MCBrowserViewController *)browserViewController{
    [[NSNotificationCenter defaultCenter] postNotificationName:kNetworkNotificationNameForConnectedPeer object:nil];
    [self.browser dismissViewControllerAnimated:YES completion:nil];
    
    [self advertiseSelf:NO];
    NSLog(@"self.session = %@", self.session);
    NSLog(@"MC - browser finished");
}

-(void)browserViewControllerWasCancelled:(MCBrowserViewController *)browserViewController{
    
    [self.browser dismissViewControllerAnimated:YES completion:nil];
    [self endSession];
    //posting a notification
    [[NSNotificationCenter defaultCenter] postNotificationName:kNetworkNotificationNameForCanceledLookingForAnOpponent object:nil];
    NSLog(@"MC - looking for opponent - cancel");
}

#pragma mark - received data

-(void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID{
    
    NSLog(@"MC - Received some data");
    //posting a notification
    [[NSNotificationCenter defaultCenter] postNotificationName:kNetworkManagerNotificationNameForReceivedData object:data];
}

#pragma mark - changed state
-(void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state{
    
    NSDictionary *dict = @{@"peerID": peerID,
                           @"state" : [NSNumber numberWithInt:state]
                           };
    
    NSLog(@"changed state  - dict = %@", dict);
    
    if (  ([dict objectForKey:@"state"] != [NSNumber numberWithInt:MCSessionStateConnected]) ){

         if ( [dict objectForKey:@"state"] == [NSNumber numberWithInt:MCSessionStateNotConnected]) {
        NSLog(@"[dict objectForKey:@'peerID'] = %@\n\n, self.peerID=%@\n\n", [dict objectForKey:@"peerID"], self.peerID);
        [[NSNotificationCenter defaultCenter] postNotificationName:kNetworkManagerNotificationNameForDisconnecting object:nil];
    }
    }
    
    if ( ([dict objectForKey:@"state"] == [NSNumber numberWithInt:MCSessionStateConnecting]) ){
        NSLog(@"[Connecting with peer = %@ \n\n", self.peerID);
        
    }
}

-(void)session:(MCSession *)session didStartReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID withProgress:(NSProgress *)progress
{
    NSLog(@"session -  didStartReceivingResourceWithName");
}

-(void)session:(MCSession *)session didReceiveStream:(NSInputStream *)stream withName:(NSString *)streamName fromPeer:(MCPeerID *)peerID
{
    NSLog(@"session -  didReceiveStream");
}
-(void)session:(MCSession *)session didFinishReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID atURL:(NSURL *)localURL withError:(NSError *)error
{
    NSLog(@"session -  didFinishReceivingResourceWithName");
}


#pragma mark - end session
- (void)endSession
{
    NSLog(@"Session (%@) is disconnecting...\n\n",self.session);
    if ( self.session ){
        //[self.session disconnect];
        [self.advertiser stop];
        
        self.session = nil;
        self.peerID = nil;
        self.session = nil;
        self.browser = nil;
        self.advertiser = nil;
        
    }
}

- (void)sendData:(NSData *)data
        withMode:(DataMode)dataMode
{
    NSError *error = nil;
    [self.session sendData:data toPeers:self.session.connectedPeers withMode:[self getMCSessionSendDataModeFromDataMode:data] error:&error];
    if ( error ){
        NSLog(@"Error in sending data - %@", [error localizedDescription]);
    }
}

- (MCSessionSendDataMode)getMCSessionSendDataModeFromDataMode:(DataMode)dataMode
{
    if ( dataMode == reliable )
    {
        return  MCSessionSendDataReliable;
    }
    return MCSessionSendDataUnreliable;
}

- (void)dismissBrowser
{
    NSLog(@"dismiss");
     [self browserViewControllerWasCancelled:self.browser];
}


@end
